home *** CD-ROM | disk | FTP | other *** search
/ Aminet 34 / Aminet 34 (2000)(Schatztruhe)[!][Dec 1999].iso / Aminet / dev / lang / Python152_Src.lha / Python152_Source / Amiga / unixemul.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-16  |  7.2 KB  |  376 lines

  1. /**************************************************************\
  2. **                                                            **
  3. **  UNIX 'emulation' functions for AmigaDOS                   **
  4. **                                                            **
  5. **  Made by Irmen de Jong (irmen@bigfoot.com)                 **
  6. **                                                            **
  7. **  21-jan-98: Created. Moved some functions from             **
  8. **             Modules/Amigamodule.c to here.                 **
  9. **  25-dec-98: Added I-Net 225 support                        **
  10. **             Added ftruncate (but not used due to bugs)     **
  11. **                                                            **
  12. **  NOTE: Don't forget __io2errno conversion!!!!!!!!!!!!!!!!  **
  13. **                                                            **
  14. \**************************************************************/
  15.  
  16. #ifndef INET225
  17. #include <dos.h>
  18. #endif
  19. #include <sys/stat.h>
  20. #include <proto/dos.h>
  21. #include <proto/exec.h>
  22. #include <dos/dostags.h>
  23. #include <exec/execbase.h>
  24. #ifdef AMITCP
  25. #include <proto/usergroup.h>
  26. #include <proto/socket.h>
  27. #endif
  28. #ifdef INET225
  29. #include <proto/socket.h>
  30. static int _OSERR;
  31. #endif
  32. #include "Python.h"
  33. #include "protos.h"
  34.  
  35. /************ Utility functions *************/
  36.  
  37. /*** checkLink: check for link loops and other errors ***/
  38. static BOOL checkLink(char *from, BPTR to, BOOL root)
  39. {
  40.     struct FileInfoBlock __aligned fib;
  41.  
  42.     if(Examine(to,&fib))
  43.     {
  44.         if(fib.fib_EntryType>0)
  45.         {
  46.             // directory! Check some things (loops etc)
  47.             char* pp;
  48.             char p;
  49.             BPTR fromLock,temp;
  50.  
  51.             // only superuser may link directories
  52.             if(!root)
  53.             {
  54.                 errno=EPERM; return FALSE;
  55.             }
  56.  
  57.             pp = PathPart(from);
  58.             p = *pp;
  59.             *pp = 0;
  60.             fromLock=Lock(from,SHARED_LOCK);
  61.             *pp=p;
  62.  
  63.             if(fromLock)
  64.             {
  65.                 do {
  66.                     if(SameLock(fromLock,to)==LOCK_SAME)
  67.                     {
  68.                         UnLock(fromLock);
  69. #ifdef ELOOP
  70.                         errno = ELOOP;
  71. #else
  72.                         errno = EMLINK;
  73. #endif
  74.                         return FALSE;       // link loop
  75.                     }
  76.  
  77.                     temp = fromLock;
  78.                     fromLock = ParentDir(fromLock);
  79.                     UnLock(temp);
  80.                 } while (fromLock);
  81.  
  82.                 return TRUE;       // dir, OK.
  83.             }
  84.             else errno=__io2errno(_OSERR=IoErr());
  85.         }
  86.         else return TRUE;      // file, OK.
  87.     }
  88.     else errno=__io2errno(_OSERR=IoErr());
  89.  
  90.     return FALSE;
  91. }
  92.  
  93.  
  94. /************ link(2) : make a hard link ************/
  95.  
  96. /* LINK: make hardlink from 'from' to 'to' (to must exist, from is new) */
  97. /* 'from' may not be a directory if you are not the super-user. */
  98. /* 0=ok, -1=err */
  99. int link(const char *to, const char *from)
  100. {
  101.     BOOL root = TRUE;
  102.     BPTR toLock;
  103.  
  104. #if defined(AMITCP) || defined(INET225)
  105.     /* are we superuser? */
  106. #ifdef AMITCP
  107.     if (!checkusergrouplib())
  108. #else /* INET */
  109.     if (!checksocketlib())
  110. #endif
  111.     {
  112.         PyErr_Clear();
  113.         root=TRUE;  /* can't tell... so be root */
  114.     }
  115.     else if(getuid()==0) root = TRUE;
  116.     else root=FALSE;
  117. #endif /* AMITCP or INET */
  118.  
  119.     if(toLock=Lock(to,SHARED_LOCK))
  120.     {
  121.         if(checkLink(from,toLock,root))
  122.         {
  123.             if(MakeLink(from,(LONG)toLock,FALSE))
  124.             {
  125.                 UnLock(toLock);
  126.                 return 0;
  127.             }
  128.             else errno=__io2errno(_OSERR=IoErr());
  129.         }
  130.         UnLock(toLock);
  131.     }
  132.     else errno=__io2errno(_OSERR=IoErr());
  133.     
  134.     return -1;
  135. }
  136.  
  137. /************** symlink(2): create symbolic (soft) link ********/
  138. int symlink(const char *to, const char *from)
  139. {
  140.     /* symbolic link 'from' is created to 'to' */
  141.     /* 0=ok, else -1 + errno */
  142.  
  143.     BPTR toLock;
  144.  
  145.     if(toLock=Lock(to,SHARED_LOCK))
  146.     {
  147.         if(checkLink(from,toLock,TRUE))
  148.         {
  149.             UnLock(toLock);
  150.             if(MakeLink(from,(LONG)to,TRUE)) return 0;
  151.             else errno=__io2errno(_OSERR=IoErr());
  152.         }
  153.         else UnLock(toLock);
  154.     }
  155.     else errno=__io2errno(_OSERR=IoErr());
  156.     
  157.     return -1;
  158. }
  159.  
  160.  
  161.  
  162. /************** readlink(2): read value of a symbolic link ***********/
  163.  
  164. int readlink(const char *path, char *buf, int bufsiz)
  165. {
  166.     struct MsgPort *port;
  167.     struct stat st;
  168.  
  169.     if(!(port=DeviceProc(path)))
  170.     {
  171.         errno=EIO; return -1;
  172.     }
  173.  
  174.     buf[bufsiz-1]=0;
  175.     errno=0;
  176.  
  177.     if(lstat(path,&st)>=0)
  178.     {
  179. #ifdef S_ISLNK
  180.         if(S_ISLNK(st.st_mode))
  181.         {
  182. #endif
  183.             char c;
  184.             BPTR dirlock;
  185.             BPTR olddir;
  186.             char *p;
  187.             char *link;
  188.  
  189.             p = PathPart(path);
  190.             link = FilePart(path);
  191.             c = *p; *p='\0';
  192.             dirlock=Lock(path,ACCESS_READ); *p=c;
  193.             if(dirlock)
  194.             {
  195.                 olddir=CurrentDir(dirlock);
  196.  
  197.                 if(!ReadLink(port,dirlock,link,buf,bufsiz))
  198.                     errno=__io2errno(_OSERR=IoErr());
  199.  
  200.                 dirlock=CurrentDir(olddir);
  201.                 UnLock(dirlock);
  202.             }   
  203.             else errno=__io2errno(_OSERR=IoErr());
  204. #ifdef S_ISLNK
  205.         }
  206.         else errno=EINVAL;
  207. #endif
  208.     }
  209.  
  210.     if(errno!=0) return -1;
  211.  
  212.     if(buf[bufsiz-1]==0) return strlen(buf);
  213.     else return bufsiz;
  214. }
  215.  
  216.  
  217.  
  218. /** custom mkdir() implementation **/
  219. /** This version actually sets protection bits **/
  220. #ifndef INET225
  221. int my_mkdir(const char* path, int p)
  222. {
  223. #ifdef AMITCP
  224.     if(checkusergrouplib()) p &= ~getumask();
  225.     else PyErr_Clear();
  226. #endif
  227.  
  228.     if(0==mkdir(path))
  229.     {
  230.         return chmod(path,p);
  231.     }
  232.     return -1;
  233. }
  234. #endif /* !INET225 */
  235.  
  236. int uname(struct utsname *u)
  237. {
  238.     int res;
  239.  
  240.     strcpy(u->sysname,"AmigaDOS");
  241.     strcpy(u->machine,"m68k");
  242. #if defined(AMITCP) || defined(INET225)
  243.     if (!checksocketlib())
  244. #endif
  245.     {
  246.         char *v;
  247.         PyErr_Clear();
  248.         res=0; v=getenv("HOSTNAME");
  249.         if(v) strcpy(u->nodename, v);
  250.         else strcpy(u->nodename, "localhost");
  251.     }
  252. #if defined(AMITCP) || defined(INET225)
  253.     else res = gethostname(u->nodename, _UNAME_BUFLEN-1);
  254. #endif
  255.     if(res>=0)
  256.     {
  257.         LONG ver_major = SysBase->LibNode.lib_Version;
  258.         LONG ver_minor = SysBase->SoftVer;
  259.         sprintf (u->release, "%d.%d", ver_major,ver_minor);
  260.         if(ver_major<36)
  261.             strcpy(u->version,"1");
  262.         else if(ver_major<39)
  263.             strcpy(u->version,"2");
  264.         else 
  265.             strcpy(u->version,"3");
  266.     }
  267.     return 0;
  268. }
  269.  
  270.  
  271. #ifndef INET225
  272. FILE *popen(const char *command, const char *type)
  273. {
  274.     char file[50];
  275.  
  276.     FILE *fh;
  277.  
  278.     static int num = 1;
  279.  
  280.     if((type[0]!='r') && (type[0]!='w'))
  281.     {
  282.         errno=EINVAL;
  283.         return 0;
  284.     }
  285.         
  286.     sprintf(file,"PIPE:Py_%ld_%ld",num++,FindTask(0));
  287.  
  288.     if(fh=fopen(file,type))
  289.     {
  290.         BPTR fh2;
  291.         LONG mode=MODE_NEWFILE; /* 'r'-peer must write */
  292.  
  293.         if(type[0]=='w') mode=MODE_OLDFILE; /* peer must read */
  294.  
  295.         if(fh2=Open(file,mode))
  296.         {
  297.             BPTR fh3;
  298.             if(type[0]=='r')
  299.             {
  300.                 /* execute command with output to fh */
  301.                 fh3=Open("*",MODE_OLDFILE); /* should use CONSOLE: */
  302.                 if(fh3 && (0==SystemTags(command,SYS_Asynch,TRUE,SYS_Output,fh2,
  303.                                     SYS_Input,fh3,TAG_DONE)))
  304.                 {
  305.                     return fh;
  306.                 }
  307.             }
  308.             else /** if(type[0]=='w') **/
  309.             {
  310.                 /* execute command with input from fh */
  311.                 fh3=Open("*",MODE_NEWFILE); /* should use CONSOLE: */
  312.                 if(fh3 && (0==SystemTags(command,SYS_Asynch,TRUE,SYS_Input,fh2,
  313.                                     SYS_Output,fh3,TAG_DONE)))
  314.                 {
  315.                     return fh;
  316.                 }
  317.             }
  318.             fclose(fh); Close(fh2); if(fh3) Close(fh3);
  319.             errno=EAGAIN;
  320.             return 0;
  321.         }
  322.         fclose(fh);
  323.     }
  324.     errno=ENOENT;
  325.     return 0;
  326. }
  327.  
  328. int pclose(FILE *stream)
  329. {
  330.     if(stream)
  331.     {
  332.         fclose(stream);
  333.         return 0;
  334.     }
  335.     errno=EINVAL;
  336.     return -1;  
  337. }
  338.  
  339. #endif /* INET225 */
  340.  
  341.  
  342. /*************** ftruncate is not yet used because of bugs in the OS FileSystem :-( ***/
  343.  
  344. #if 0
  345.  
  346. int ftruncate(int fd, long newlength)
  347. {
  348.   struct UFB *ufb;
  349.  
  350.   /*
  351.    * find the ufb *
  352.    */
  353.   if ((ufb = __chkufb(fd)) != NULL && !(ufb->ufbflg & UFB_SOCK))
  354.   {
  355.     if(-1==SetFileSize(ufb->ufbfh,newlength,OFFSET_BEGINNING))
  356.     {
  357.         set_errno(IoErr());
  358.         return -1;
  359.     }
  360.     return 0;
  361.   }
  362.   
  363.   errno = EINVAL;
  364.   return -1;
  365. }
  366.  
  367. #endif
  368.  
  369.  
  370. /********************* getpid ***********************/
  371.  
  372. pid_t getpid(void)
  373. {
  374.     return (pid_t)SysBase->ThisTask;
  375. }
  376.